#pragma once

#include <memory>
#include <QString>
#include <QByteArray>
#include <QMutex>
#include "CharType.h"
#include "ISimpleChannel.h"


class Tape : public QObject
{
    Q_OBJECT

public:
    Tape(CharType::EType type = CharType::DATA);

public:
    bool HasChars();  
    
    void Reset();
    void SetCharAgent(ISimpleChannelPtr agent);
    void SetCharsLookUp(const CharTypeList& _charlist);
    
    CharType::EType Type();
    CharTypePtr Next();    
    QString LastError();

public slots:
    void PutChar(const QByteArray& chars);
    void PutChar(Char code);

public slots:
    void PlaceTimeoutChar();

signals:
    void NewData();

private:
    unsigned GetTapeReadPosition(CharTypePtr character);
    unsigned GetBytesCountToRead();

private:
    unsigned MatchCharList(CharTypePtr character);
    unsigned MatchRegExp(CharTypePtr character);

private:
    ISimpleChannelPtr   _charAgent;
    CharTypePtr         _currentChar;
    CharType::EType     _myType;    
    CharTypeList        _charList;
    QByteArray          _tape;
    QString             _error;
    QMutex              _mutex;
};

typedef std::tr1::shared_ptr<Tape> TapePtr;